import type { FormInstance } from 'ant-design-vue/lib/form/Form';
import type {
  RuleObject,
  NamePath,
  Rule as ValidationRule,
} from 'ant-design-vue/lib/form/interface';
import { ref, computed, unref, Ref } from 'vue';
import { useI18n } from '@/hooks/web/useI18n';

import { isEmail, isMobileNumber } from '@/enums/regexEnum';

import { checkUserNameExists, checkEmailExists, checkPhoneNumberExists } from '@/api/identity';
import { VerifyCodeConfirmDto } from '@/api/sms/model';
import { checkSmsVerifyCode } from '@/api/sms';
import { checkVerifyCode } from '@/api/sys';
import { AjaxResult } from '@/api/model';
import { AjaxResultTypeEnum } from '@/enums/ajaxResultTypeEnum';

/** 登录状态枚举 */
export enum LoginStateEnum {
  /** 登录 */
  LOGIN,
  /** 注册 */
  REGISTER,
  /** 注册结果 */
  REGISTER_RESULT,
  /** 重置密码 */
  RESET_PASSWORD,
  /** 手机登录 */
  MOBILE,
  /** 二维码登录 */
  QR_CODE,
  /** 发送邮箱激活邮件 */
  SEND_CONFIRM_EMAIL,
  /** 激活手机 */
  CONFIRM_PHONE,
  /** 激活结果 */
  CONFIRM_RESULT,
}

/** 当前登录状态 */
const currentState = ref(LoginStateEnum.LOGIN);

// 这里也可以优化
// import { createGlobalState } from '@vueuse/core'

/** Ajax结果 */
const ajaxResult: AjaxResult = {
  Type: AjaxResultTypeEnum.Success,
  Content: '',
  Data: null,
  Succeeded: true,
  Failed: false,
};
/** Ajax结果状态 */
const ajaxResultState = ref(ajaxResult);

/** 用户账户状态 */
const userAccountState = ref('');

/** 使用登录状态 */
export function useLoginState() {
  /**
   * 设置登录状态
   * @param state 登录状态
   */
  function setLoginState(state: LoginStateEnum) {
    currentState.value = state;
  }

  /** 获取登录状态 */
  const getLoginState = computed(() => currentState.value);

  /** 处理返回登录 */
  function handleBackLogin() {
    setLoginState(LoginStateEnum.LOGIN);
  }

  /**
   * 处理响应结果
   * @param ajaxResult 响应结果
   * @param state 登录状态
   */
  function handleAjaxResult(ajaxResult: AjaxResult, state: LoginStateEnum) {
    ajaxResultState.value = ajaxResult;
    setLoginState(state);
  }

  /** 获取响应结果状态 */
  const getAjaxResultState = computed(() => ajaxResultState.value);

  /**
   * 设置用户账户
   * @param userAccount 用户账户
   */
  function setUserAccount(userAccount: string) {
    userAccountState.value = userAccount;
  }

  /** 获取用户账户状态 */
  const getUserAccountState = computed(() => userAccountState.value);

  return {
    setLoginState,
    getLoginState,
    handleBackLogin,
    handleAjaxResult,
    getAjaxResultState,
    setUserAccount,
    getUserAccountState,
  };
}

/** 使用表单验证 */
export function useFormValid<T extends Object = any>(formRef: Ref<FormInstance>) {
  const validate = computed(() => {
    const form = unref(formRef);
    return form?.validate ?? ((_nameList?: NamePath) => Promise.resolve());
  });

  /** 验证表单 */
  async function validForm() {
    const form = unref(formRef);
    if (!form) return;
    const data = await form.validate();
    return data as T;
  }

  return { validate, validForm };
}

/** 使用表单规则 */
export function useFormRules(formData?: Recordable) {
  const { t } = useI18n();

  const getUserNameFormRule = computed(() => createRule(t('sys.login.userNamePlaceholder')));
  const getNickNameFormRule = computed(() => createRule(t('sys.login.nickNamePlaceholder')));
  const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder')));
  // const getConfirmPasswordFormRule = computed(() => createRule(t('sys.login.confirmPasswordPlaceholder')));
  // const getEmailFormRule = computed(() => createRule(t('sys.login.emailPlaceholder')));
  // const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder')));
  // const getSmsCodeFormRule = computed(() => createRule(t('sys.login.smsCodePlaceholder')));
  // const getOrganizationIdFormRule = computed(() => createRule(t('sys.login.organizationIdPlaceholder')));
  // const getVerifyCodeFormRule = computed(() => createRule(t('sys.login.verifyCodePlaceholder')));

  /**
   * 验证勾选XXX协议
   * @param _
   * @param value
   * @returns
   */

  const validatePolicy = async (_: RuleObject, value: boolean) => {
    return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve();
  };

  /**
   * 验证确认密码
   * @param password 密码
   * @returns
   */
  const validateConfirmPassword = (password: string) => {
    return async (_: RuleObject, value: string) => {
      if (!value) {
        return Promise.reject(t('sys.login.passwordPlaceholder'));
      }
      if (value !== password) {
        return Promise.reject(t('sys.login.diffPwd'));
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证账户
   * @returns
   */
  const validateUserName = (existed = true) => {
    return async (_: RuleObject, value: string) => {
      if (!value) {
        return Promise.reject(t('sys.login.userNamePlaceholder'));
      }
      if (existed) {
        if (await checkUserNameExists(value)) {
          return Promise.reject(t('sys.login.userNameExisted'));
        }
      } else {
        if (!(await checkUserNameExists(value))) {
          return Promise.reject(t('sys.login.userNameNotExisted'));
        }
      }

      return Promise.resolve();
    };
  };

  /**
   * 验证邮箱
   * @param existed 已存在验证，true表示如果已存在则验证不通过
   * @returns
   */
  const validateEmail = (existed = true) => {
    return async (_: RuleObject, value: string) => {
      if (!value) {
        return Promise.resolve();
      }
      if (!isEmail(value)) {
        return Promise.reject(t('sys.login.emailFormatError'));
      }
      if (existed) {
        if (await checkEmailExists(value)) {
          return Promise.reject(t('sys.login.emailExisted'));
        }
      } else {
        if (!(await checkEmailExists(value))) {
          return Promise.reject(t('sys.login.emailNotExisted'));
        }
      }

      return Promise.resolve();
    };
  };

  /**
   * 验证手机号码
   * @param required 是否必填
   * @param existed 已存在验证，true表示如果已存在则验证不通过
   * @returns
   */
  const validatePhoneNumber = (required: boolean, existed = true) => {
    return async (_: RuleObject, value: string) => {
      if (value === undefined || value === null || value === '') {
        if (required === true) {
          return Promise.reject(t('sys.login.mobilePlaceholder'));
        }
        return Promise.resolve();
      }
      if (!isMobileNumber(value)) {
        return Promise.reject(t('sys.login.mobileFormatError'));
      }
      if (existed) {
        if (await checkPhoneNumberExists(value)) {
          return Promise.reject(t('sys.login.mobileExisted'));
        }
      } else {
        if (!(await checkPhoneNumberExists(value))) {
          return Promise.reject(t('sys.login.mobileNotExisted'));
        }
      }

      return Promise.resolve();
    };
  };

  /**
   * 验证短信验证码
   * @param mobile 手机号码
   * @param smsCodeId 短信验证码编号
   * @returns
   */
  const validateSmsCode = (mobile: string, smsCodeId: string) => {
    return async (_: RuleObject, value: string) => {
      if (mobile === undefined || mobile === null || mobile === '') {
        return Promise.resolve();
      }
      if (value === undefined || value === null || value === '') {
        return Promise.reject(t('sys.login.smsCodePlaceholder'));
      }
      if (smsCodeId === undefined || smsCodeId === null || smsCodeId === '') {
        return Promise.reject(t('sys.login.smsCodeInvalid'));
      }
      const dto: VerifyCodeConfirmDto = {
        PhoneNumber: mobile,
        Code: value,
        CodeId: smsCodeId,
      };
      if (!(await checkSmsVerifyCode(dto))) {
        return Promise.reject(t('sys.login.smsCodeInvalid'));
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证验证码
   * @param verifyCodeId 验证码编号
   * @returns
   */
  const validateVerifyCode = (verifyCodeId: string) => {
    return async (_: RuleObject, value: string) => {
      if (value === undefined || value === null || value === '') {
        return Promise.reject(t('sys.login.verifyCodePlaceholder'));
      }
      if (verifyCodeId === undefined || verifyCodeId === null || verifyCodeId === '') {
        return Promise.reject(t('sys.login.verifyCodeInvalid'));
      }
      if (!(await checkVerifyCode(value, verifyCodeId))) {
        return Promise.reject(t('sys.login.verifyCodeInvalid'));
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证用户账户
   * @param userNameType 账户类型，1-手机、2-邮箱
   * @returns
   */
  const validateUserAccount = (userNameType: string) => {
    return async (_: RuleObject, value: string) => {
      if (value === undefined || value === null || value === '') {
        return Promise.reject(t('sys.login.userNamePlaceholder'));
      }
      if (userNameType === '1') {
        if (!isMobileNumber(value)) {
          return Promise.reject(t('sys.login.mobileFormatError'));
        }
        if (!(await checkPhoneNumberExists(value))) {
          return Promise.reject(t('sys.login.mobileNotExisted'));
        }
      }
      if (userNameType === '2') {
        if (!isEmail(value)) {
          return Promise.reject(t('sys.login.emailFormatError'));
        }
        if (!(await checkEmailExists(value))) {
          return Promise.reject(t('sys.login.emailNotExisted'));
        }
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证短信验证码-重置密码
   * @param mobile 手机号码
   * @param smsCodeId 短信验证码编号
   * @param userNameType 账户类型，1-手机、2-邮箱
   * @param currentStep 当前节点
   * @returns
   */
  const validateSmsCodeResetPassword = (
    mobile: string,
    smsCodeId: string,
    userNameType: string,
    currentStep: number,
  ) => {
    return async (_: RuleObject, value: string) => {
      if (userNameType === '1' && currentStep === 1) {
        if (mobile === undefined || mobile === null || mobile === '') {
          return Promise.resolve();
        }
        if (value === undefined || value === null || value === '') {
          return Promise.reject(t('sys.login.smsCodePlaceholder'));
        }
        if (smsCodeId === undefined || smsCodeId === null || smsCodeId === '') {
          return Promise.reject(t('sys.login.smsCodeInvalid'));
        }
        const dto: VerifyCodeConfirmDto = {
          PhoneNumber: mobile,
          Code: value,
          CodeId: smsCodeId,
        };
        if (!(await checkSmsVerifyCode(dto))) {
          return Promise.reject(t('sys.login.smsCodeInvalid'));
        }
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证密码-重置密码
   * @param userNameType 账户类型，1-手机、2-邮箱
   * @param currentStep 当前节点
   * @returns
   */
  const validateNewPasswordResetPassword = (userNameType: string, currentStep: number) => {
    return async (_: RuleObject, value: string) => {
      if (userNameType === '1' && currentStep === 1) {
        if (value === undefined || value === null || value === '') {
          return Promise.reject(t('sys.login.passwordPlaceholder'));
        }
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证确认密码-重置密码
   * @param password 密码
   * @param userNameType 账户类型，1-手机、2-邮箱
   * @param currentStep 当前节点
   * @returns
   */
  const validateConfirmPasswordResetPassword = (
    password: string,
    userNameType: string,
    currentStep: number,
  ) => {
    return async (_: RuleObject, value: string) => {
      if (userNameType === '1' && currentStep === 1) {
        if (value === undefined || value === null || value === '') {
          return Promise.reject(t('sys.login.confirmPasswordPlaceholder'));
        }
        if (value !== password) {
          return Promise.reject(t('sys.login.diffPwd'));
        }
      }
      return Promise.resolve();
    };
  };

  /**
   * 验证验证码
   * @param verifyCodeId 验证码编号
   * @param userNameType 账户类型，1-手机、2-邮箱
   * @param currentStep 当前节点
   * @returns
   */
  const validateVerifyCodeResetPassword = (
    verifyCodeId: string,
    userNameType: string,
    currentStep: number,
  ) => {
    return async (_: RuleObject, value: string) => {
      if (userNameType === '2' && currentStep === 1) {
        if (value === undefined || value === null || value === '') {
          return Promise.reject(t('sys.login.verifyCodePlaceholder'));
        }
        if (verifyCodeId === undefined || verifyCodeId === null || verifyCodeId === '') {
          return Promise.reject(t('sys.login.verifyCodeInvalid'));
        }
        if (!(await checkVerifyCode(value, verifyCodeId))) {
          return Promise.reject(t('sys.login.verifyCodeInvalid'));
        }
      }
      return Promise.resolve();
    };
  };

  /** 获取表单规则 */
  const getFormRules = computed((): { [k: string]: ValidationRule | ValidationRule[] } => {
    const userNameFormRule = unref(getUserNameFormRule);
    const nickNameFormRule = unref(getNickNameFormRule);
    const passwordFormRule = unref(getPasswordFormRule);
    // const confirmPasswordFormRule = unref(getConfirmPasswordFormRule);
    // const emailFormRule = unref(getEmailFormRule);
    // const mobileFormRule = unref(getMobileFormRule);
    // const smsCodeFormRule = unref(getSmsCodeFormRule);
    // const organizationIdFormRule = unref(getOrganizationIdFormRule);
    // const verifyCodeFormRule = unref(getVerifyCodeFormRule);

    // const mobileRule = {
    //   mobile: mobileFormRule,
    //   smsCode: smsCodeFormRule,
    // };
    switch (unref(currentState)) {
      // 注册表单规则（register form rules）
      case LoginStateEnum.REGISTER:
        return {
          userName: [{ validator: validateUserName(), trigger: 'change' }],
          nickName: nickNameFormRule,
          password: passwordFormRule,
          confirmPassword: [
            { validator: validateConfirmPassword(formData?.password), trigger: 'change' },
          ],
          email: [{ validator: validateEmail(), trigger: 'change' }],
          mobile: [{ validator: validatePhoneNumber(false, true), trigger: 'change' }],
          smsCode: [
            {
              validator: validateSmsCode(formData?.mobile, formData?.smsCodeId),
              trigger: 'change',
            },
          ],
          verifyCode: [
            {
              validator: validateVerifyCode(formData?.verifyCodeId),
              trigger: 'change',
            },
          ],
          policy: [{ validator: validatePolicy, trigger: 'change' }],
        };

      // 发送邮箱激活邮件表单规则
      case LoginStateEnum.SEND_CONFIRM_EMAIL:
        return {
          email: [{ validator: validateEmail(false), trigger: 'change' }],
          verifyCode: [
            {
              validator: validateVerifyCode(formData?.verifyCodeId),
              trigger: 'change',
            },
          ],
        };

      // 激活手机表单规则
      case LoginStateEnum.CONFIRM_PHONE:
        return {
          mobile: [{ validator: validatePhoneNumber(true, false), trigger: 'change' }],
          smsCode: [
            {
              validator: validateSmsCode(formData?.mobile, formData?.smsCodeId),
              trigger: 'change',
            },
          ],
        };

      // 重置密码表单规则（reset password form rules）
      case LoginStateEnum.RESET_PASSWORD:
        return {
          userName: [{ validator: validateUserAccount(formData?.userNameType), trigger: 'change' }],
          smsCode: [
            {
              validator: validateSmsCodeResetPassword(
                formData?.userName,
                formData?.smsCodeId,
                formData?.userNameType,
                formData?.currentStep,
              ),
              trigger: 'change',
            },
          ],
          newPassword: [
            {
              validator: validateNewPasswordResetPassword(
                formData?.userNameType,
                formData?.currentStep,
              ),
              trigger: 'change',
            },
          ],
          confirmPassword: [
            {
              validator: validateConfirmPasswordResetPassword(
                formData?.newPassword,
                formData?.userNameType,
                formData?.currentStep,
              ),
              trigger: 'change',
            },
          ],
          verifyCode: [
            {
              validator: validateVerifyCodeResetPassword(
                formData?.verifyCodeId,
                formData?.userNameType,
                formData?.currentStep,
              ),
              trigger: 'change',
            },
          ],
        };

      // 手机登录表单规则（mobile form rules）
      case LoginStateEnum.MOBILE:
        return {
          mobile: [{ validator: validatePhoneNumber(true, false), trigger: 'change' }],
          smsCode: [
            {
              validator: validateSmsCode(formData?.mobile, formData?.smsCodeId),
              trigger: 'change',
            },
          ],
        };

      // 默认登录表单规则（login form rules）
      default:
        return {
          userName: userNameFormRule,
          password: passwordFormRule,
        };
    }
  });
  return { getFormRules };
}

/** 创建规则 */
function createRule(message: string): ValidationRule[] {
  return [
    {
      required: true,
      message,
      trigger: 'change',
    },
  ];
}
